/**
 * @Name:
 * @Author:
 * @Desc:
 * @Date: 2021-02-04 14:54:53
 */
/*
使用-页面内部-即用即关类型
01、引入
import { WBT } from '@/utils/socket'
02、声明socket
socket = null
03、打开socket-绑定回调方法
initWBT = () => {
  if (!this.socket) {
    const callbackSet = {
      socketSaveResult: this.socketSaveResult,
    }
    this.socket = new WBT(callbackSet)
  }
}
04、接收消息-判断返回code-进行之后操作
socketSaveResult=(res)=>{}
05、如果不需要socket-例如离开当前页面-关闭socket
if (this.socket) {
  this.socket.shutDown()
}
*/
/**
 * @param {Object} callbackSet 回调集合
 */
const WBT = function (callbackSet) {
  /*
    websocket接口地址
    1、http请求还是https请求 前缀不一样
	  2、ip地址host
    3、端口号
  */
  const protocol = window.location.protocol == "http:" ? "ws://" : "wss://";
  const host = window.location.host; // 'www.baidu.com' window.location.host
  // 接口地址url
  this.url = protocol + host + "/websocket/ws"; //ws://www.baidu.com/websocket/ws
  // socket对象
  this.socket = null;
  // 重连延迟
  this.socketTime = null;
  // 重连状态 避免不间断的重连操作
  this.isReconnect = false;
  // 离开备课中心页不重连判断
  this.isClose = false;
  // 成功返回的参数
  this.actionParam = null;

  // 心跳包
  this.heartCheck = {
    timeout: 120000,
    timeoutObj: null,
    serverTimeoutObj: null,
    reset: function () {
      clearTimeout(this.timeoutObj);
      clearTimeout(this.serverTimeoutObj);
      return this;
    },
    start: function (ws) {
      const self = this;
      this.serverTimeoutObj = setTimeout(() => {
        let token = window.localStorage.getItem("token");
        let send = { topic: "服务器地址-建立握手", tags: "SAY_HELLO", token: token, param: "" };
        if (ws) {
          ws.send(JSON.stringify(send));
          self.timeoutObj = setTimeout(function () {
            ws.close();
          }, self.timeout);
        }
      }, this.timeout);
    }
  };

  // 自定义ws连接函数：服务器连接成功
  this.onopen = (e) => {
    this.heartCheck.reset().start(this.socket);
    console.log("Socket连接已经打开");
  };
  // 自定义ws消息接收函数：服务器向前端推送消息时触发
  this.onmessage = (msg) => {
    this.heartCheck.reset().start(this.socket);
    try {
      let value = JSON.parse(msg.data);
      // let value = msg.data
      if (value instanceof Object && value.actionCode) {
        this.handleEvent(value, callbackSet);
      }
    } catch (error) {
      console.error("获取信息失败", error);
    }
  };
  // 自定义ws异常事件：ws报错后触发
  this.onerror = (e) => {
    console.log("error", e);
    this.reConnect();
  };
  // 自定义ws关闭事件：ws连接关闭后触发
  this.onclose = () => {
    if (!this.isClose) {
      this.heartCheck.reset();
      this.reConnect();
      console.log("reConnect");
    }
  };

  this.shutDown = () => {
    this.isClose = true;
    this.heartCheck.reset();
    this.socket.close();
    console.log("Socket连接已断开");
  };

  this.initWs();
};

// 初始化websocket连接
WBT.prototype.initWs = function () {
  window.WebSocket = window.WebSocket || window.MozWebSocket;
  // 检测浏览器支持
  if (!window.WebSocket) {
    console.error("错误: 浏览器不支持websocket");
    return;
  }
  let token = window.localStorage.getItem("token");
  if (token) {
    this.socket = new WebSocket(this.url);

    this.socket.onopen = (e) => {
      let send = { topic: "服务器地址-建立握手", tags: "SAY_HELLO", token: token, param: "" };
      this.socket.send(JSON.stringify(send));
      this.onopen(e);
    };
    this.socket.onmessage = (msg) => {
      console.log("msg=socket==", msg);
      this.onmessage(msg);
    };
    this.socket.onerror = (e) => {
      this.onerror(e);
    };
    this.socket.onclose = (e) => {
      this.onclose(e);
    };
    return this;
  } else {
    this.reConnect();
  }
};

// 断线重连
WBT.prototype.reConnect = function () {
  if (this.isReconnect) return;
  if (this.socketTime) {
    clearTimeout(this.socketTime);
  }
  this.isReconnect = true;
  // 没连上会一直重连，设置延迟避免请求过多
  this.socketTime = setTimeout(() => {
    this.initWs();
    this.isReconnect = false;
  }, 2000);
};

// 处理消息
WBT.prototype.handleEvent = function (value, callbackSet) {
  const action = value.actionCode;

  console.log("handleEvent 消息处理", { value, callbackSet });
  // 根据action和retCode处理事件
  if (this.handleAction[action]) this.handleAction[action](value, callbackSet);
};
//接收后端返回socket-code,并回调相应方法
WBT.prototype.handleAction = {
  // 另存成功
  "save-sockets": (value, callbackSet) => {
    const data = value ? JSON.parse(value.actionParam) : null;
    callbackSet.socketSaveChange(data);
  }
};

export { WBT };
